import 'package:flutter/material.dart';
import 'package:intl/intl.dart';

class UserProfile {
  final int? id;
  final String name;
  final DateTime birthDate;
  final int height;
  final int weight;
  final String bloodType;
  final DateTime lastPeriodDate;
  final int cycleLength;
  final int periodLength;
  final String currentMode;
  final bool notificationsEnabled;
  final bool darkMode;
  final List<String> healthConditions;
  final bool isUsingBirthControl;
  final int? reminderDays;
  
  
  int get age {
    final now = DateTime.now();
    int age = now.year - birthDate.year;
    if (now.month < birthDate.month || (now.month == birthDate.month && now.day < birthDate.day)) {
      age--;
    }
    return age;
  }

  UserProfile({
    this.id,
    required this.name,
    required this.birthDate,
    required this.height,
    required this.weight,
    required this.bloodType,
    required this.lastPeriodDate,
    required this.cycleLength,
    required this.periodLength,
    required this.currentMode,
    required this.notificationsEnabled,
    required this.darkMode,
    this.healthConditions = const [],
    this.isUsingBirthControl = false,
    this.reminderDays,
  });

  UserProfile copyWith({
    int? id,
    String? name,
    DateTime? birthDate,
    int? height,
    int? weight,
    String? bloodType,
    DateTime? lastPeriodDate,
    int? cycleLength,
    int? periodLength,
    String? currentMode,
    bool? notificationsEnabled,
    bool? darkMode,
    List<String>? healthConditions,
    bool? isUsingBirthControl,
    int? reminderDays,
  }) {
    return UserProfile(
      id: id ?? this.id,
      name: name ?? this.name,
      birthDate: birthDate ?? this.birthDate,
      height: height ?? this.height,
      weight: weight ?? this.weight,
      bloodType: bloodType ?? this.bloodType,
      lastPeriodDate: lastPeriodDate ?? this.lastPeriodDate,
      cycleLength: cycleLength ?? this.cycleLength,
      periodLength: periodLength ?? this.periodLength,
      currentMode: currentMode ?? this.currentMode,
      notificationsEnabled: notificationsEnabled ?? this.notificationsEnabled,
      darkMode: darkMode ?? this.darkMode,
      healthConditions: healthConditions ?? this.healthConditions,
      isUsingBirthControl: isUsingBirthControl ?? this.isUsingBirthControl,
      reminderDays: reminderDays ?? this.reminderDays,
    );
  }

  
  factory UserProfile.fromMap(Map<String, dynamic> map) {
    return UserProfile(
      id: map['id'] as int?,
      name: map['name'] as String,
      birthDate: DateTime.parse(map['birth_date'] as String),
      height: map['height'] as int,
      weight: map['weight'] as int,
      bloodType: map['blood_type'] as String,
      lastPeriodDate: DateTime.parse(map['last_period_date'] as String),
      cycleLength: map['cycle_length'] is String ? int.tryParse(map['cycle_length'] as String) ?? 28 : map['cycle_length'] as int,
      periodLength: map['period_length'] is String ? int.tryParse(map['period_length'] as String) ?? 5 : map['period_length'] as int,
      currentMode: map['current_mode'] as String,
      notificationsEnabled: (map['notifications_enabled'] as int) == 1,
      darkMode: (map['dark_mode'] as int) == 1,
      healthConditions: _parseHealthConditions(map['health_conditions']),
      isUsingBirthControl: (map['is_using_birth_control'] as int?) == 1,
      reminderDays: map['reminder_days'] as int?,
    );
  }

  
  static List<String> _parseHealthConditions(dynamic value) {
    if (value == null) return const [];
    if (value is String) {
      return value
          .split(',')
          .map((e) => e.trim())
          .where((e) => e.isNotEmpty)
          .toList();
    }
    return const [];
  }

  
  Map<String, dynamic> toMap() {
    return {
      if (id != null) 'id': id,
      'name': name,
      'birth_date': birthDate.toIso8601String().split('T')[0],
      'height': height,
      'weight': weight,
      'blood_type': bloodType,
      'last_period_date': lastPeriodDate.toIso8601String().split('T')[0],
      'cycle_length': cycleLength,
      'period_length': periodLength,
      'current_mode': currentMode,
      'notifications_enabled': notificationsEnabled ? 1 : 0,
      'dark_mode': darkMode ? 1 : 0,
      'health_conditions': healthConditions.join(','),
      'is_using_birth_control': isUsingBirthControl ? 1 : 0,
      if (reminderDays != null) 'reminder_days': reminderDays,
      'updated_at': DateTime.now().toIso8601String(),
    };
  }
}

class PeriodModel {
  final int? id;
  final DateTime date;
  final bool isPeriod;
  final bool isOvulation;
  final bool isToday;
  final bool isPredictedPeriod;
  final bool isPossiblePeriod;
  final String? mood;
  final String? symptoms;
  final String? notes;
  final double? flowLevel;
  final double? painLevel;
  final double? weight; 


  PeriodModel({
    this.id,
    required this.date,
    required this.isPeriod,
    required this.isOvulation,
    required this.isToday,
    required this.isPredictedPeriod,
    required this.isPossiblePeriod,
    this.mood,
    this.symptoms,
    this.notes,
    this.flowLevel,
    this.painLevel,
    this.weight, 

  });

  PeriodModel copyWith({
    int? id,
    DateTime? date,
    bool? isPeriod,
    bool? isOvulation,
    bool? isToday,
    bool? isPredictedPeriod,
    bool? isPossiblePeriod,
    String? mood,
    String? symptoms,
    String? notes,
    double? flowLevel,
    double? painLevel,
    double? weight,
  }) {
    return PeriodModel(
      id: id ?? this.id,
      date: date ?? this.date,
      isPeriod: isPeriod ?? this.isPeriod,
      isOvulation: isOvulation ?? this.isOvulation,
      isToday: isToday ?? this.isToday,
      isPredictedPeriod: isPredictedPeriod ?? this.isPredictedPeriod,
      isPossiblePeriod: isPossiblePeriod ?? this.isPossiblePeriod,
      mood: mood ?? this.mood,
      symptoms: symptoms ?? this.symptoms,
      notes: notes ?? this.notes,
      flowLevel: flowLevel ?? this.flowLevel,
      painLevel: painLevel ?? this.painLevel,
      weight: weight ?? this.weight, 

    );
  }
  
  factory PeriodModel.fromMap(Map<String, dynamic> map) {
    return PeriodModel(
      date: DateTime.parse(map['date'] as String),
      isPeriod: (map['is_period'] as int) == 1,
      isOvulation: (map['is_ovulation'] as int) == 1,
      isToday: (map['is_today'] as int) == 1,
      isPredictedPeriod: (map['is_predicted_period'] as int) == 1,
      isPossiblePeriod: (map['is_possible_period'] as int) == 1,
      mood: map['mood'] as String?,
      symptoms: map['symptoms'] as String?,
      notes: map['notes'] as String?,
      flowLevel: map['flow_level'] as double?,
      painLevel: map['pain_level'] as double?,
      weight: map['weight'] as double?,
    );
  }

  
  Map<String, dynamic> toMap() {
    return {
      'date': date.toIso8601String().split('T')[0],
      'is_period': isPeriod ? 1 : 0,
      'is_ovulation': isOvulation ? 1 : 0,
      'is_today': isToday ? 1 : 0,
      'is_predicted_period': isPredictedPeriod ? 1 : 0,
      'is_possible_period': isPossiblePeriod ? 1 : 0,
      if (mood != null) 'mood': mood,
      if (symptoms != null) 'symptoms': symptoms,
      if (notes != null) 'notes': notes,
      if (flowLevel != null) 'flow_level': flowLevel,
      if (painLevel != null) 'pain_level': painLevel,
      if (weight != null) 'weight': weight,
      'updated_at': DateTime.now().toIso8601String(),
    };
  }
}

class CycleInfo {
  final int cycleLength;
  final int periodLength;
  final DateTime nextPeriodDate;
  final DateTime ovulationDate;
  final double pregnancyRate;
  final int daysUntilNextPeriod;
  final int daysUntilOvulation;
  final int healthScore;
  final String healthStatus;
  final String fertilityWindow;
  final List<String> recommendations;
  final int predictionConfidence; 

  // 从Map创建CycleInfo对象的工厂方法
  factory CycleInfo.fromMap(Map<String, dynamic> map) {
    return CycleInfo(
      cycleLength: map['cycleLength'] ?? 28,
      periodLength: map['periodLength'] ?? 5,
      nextPeriodDate: map['nextPeriodDate'] is String 
          ? DateTime.parse(map['nextPeriodDate'])
          : DateTime.now().add(Duration(days: 28)),
      ovulationDate: map['ovulationDate'] is String
          ? DateTime.parse(map['ovulationDate'])
          : DateTime.now().add(Duration(days: 14)),
      pregnancyRate: map['pregnancyRate'] ?? 0.0,
      daysUntilNextPeriod: map['daysUntilNextPeriod'] ?? 28,
      daysUntilOvulation: map['daysUntilOvulation'] ?? 14,
      healthScore: map['healthScore'] ?? 85,
      healthStatus: map['healthStatus'] ?? '良好',
      fertilityWindow: map['fertilityWindow'] ?? '非受孕窗口期',
      recommendations: map['recommendations'] is List 
          ? List<String>.from(map['recommendations'])
          : ['保持健康作息', '注意营养均衡'],
      predictionConfidence: map['predictionConfidence'] ?? 50,
    );
  }

  CycleInfo({
    required this.cycleLength,
    required this.periodLength,
    required this.nextPeriodDate,
    required this.ovulationDate,
    required this.pregnancyRate,
    required this.daysUntilNextPeriod,
    required this.daysUntilOvulation,
    required this.healthScore,
    required this.healthStatus,
    required this.fertilityWindow,
    required this.recommendations,
    this.predictionConfidence = 50, 

  });
}

class UserRecord {
  final String type;
  final String? value;
  final DateTime date;
  final String? notes;
  final String? category;
  final double? intensity;

  UserRecord({
    required this.type,
    this.value,
    required this.date,
    this.notes,
    this.category,
    this.intensity,
  });
}

class AppSettings {
  final bool notificationsEnabled;
  final bool darkMode;
  final String language;
  final String temperatureUnit;
  final bool healthDataSharing;
  final bool backupEnabled;
  final DateTime lastBackup;

  AppSettings({
    required this.notificationsEnabled,
    required this.darkMode,
    required this.language,
    required this.temperatureUnit,
    required this.healthDataSharing,
    required this.backupEnabled,
    required this.lastBackup,
  });

  AppSettings copyWith({
    bool? notificationsEnabled,
    bool? darkMode,
    String? language,
    String? temperatureUnit,
    bool? healthDataSharing,
    bool? backupEnabled,
    DateTime? lastBackup,
  }) {
    return AppSettings(
      notificationsEnabled: notificationsEnabled ?? this.notificationsEnabled,
      darkMode: darkMode ?? this.darkMode,
      language: language ?? this.language,
      temperatureUnit: temperatureUnit ?? this.temperatureUnit,
      healthDataSharing: healthDataSharing ?? this.healthDataSharing,
      backupEnabled: backupEnabled ?? this.backupEnabled,
      lastBackup: lastBackup ?? this.lastBackup,
    );
  }
}

class HealthMetrics {
  final double bmi;
  final String bmiCategory;
  final int restingHeartRate;
  final int sleepHours;
  final int steps;
  final double waterIntake;
  final String stressLevel;

  HealthMetrics({
    required this.bmi,
    required this.bmiCategory,
    required this.restingHeartRate,
    required this.sleepHours,
    required this.steps,
    required this.waterIntake,
    required this.stressLevel,
  });
}

// 经期记录模型
class Period {
  final int? id;
  final DateTime startDate;
  final DateTime endDate;
  final int flowIntensity; // 1-5，1最轻，5最重
  final String? note;
  final int userId;

  Period({
    this.id,
    required this.startDate,
    required this.endDate,
    this.flowIntensity = 3,
    this.note,
    required this.userId,
  });

  // 获取经期长度
  int get length => endDate.difference(startDate).inDays + 1;

  // 判断是否包含指定日期
  bool containsDate(DateTime date) {
    return date.isAfter(startDate.subtract(Duration(days: 1))) && 
           date.isBefore(endDate.add(Duration(days: 1)));
  }

  Map<String, dynamic> toMap() {
    return {
      'startDate': DateFormat('yyyy-MM-dd').format(startDate),
      'endDate': DateFormat('yyyy-MM-dd').format(endDate),
      'flowIntensity': flowIntensity,
      'note': note,
      'userId': userId,
    };
  }

  factory Period.fromMap(Map<String, dynamic> map) {
    return Period(
      id: map['id'],
      startDate: DateTime.parse(map['startDate']),
      endDate: DateTime.parse(map['endDate']),
      flowIntensity: map['flowIntensity'],
      note: map['note'],
      userId: map['userId'],
    );
  }

  String getFlowIntensityText() {
    switch (flowIntensity) {
      case 1: return '极轻微';
      case 2: return '轻微';
      case 3: return '适中';
      case 4: return '较重';
      case 5: return '严重';
      default: return '适中';
    }
  }
}

// 症状记录模型
class Symptom {
  final int? id;
  final String name;
  final int severity; // 1-10，1最轻，10最重
  final DateTime date;
  final int? periodId;

  Symptom({
    this.id,
    required this.name,
    this.severity = 5,
    required this.date,
    this.periodId,
  });

  Map<String, dynamic> toMap() {
    return {
      'name': name,
      'severity': severity,
      'date': DateFormat('yyyy-MM-dd').format(date),
      'periodId': periodId,
    };
  }

  factory Symptom.fromMap(Map<String, dynamic> map) {
    return Symptom(
      id: map['id'],
      name: map['name'],
      severity: map['severity'],
      date: DateTime.parse(map['date']),
      periodId: map['periodId'],
    );
  }

  String getSeverityText() {
    if (severity <= 3) return '轻微';
    if (severity <= 6) return '中等';
    if (severity <= 8) return '严重';
    return '非常严重';
  }

  Color getSeverityColor() {
    if (severity <= 3) return Colors.green.shade200;
    if (severity <= 6) return Colors.yellow.shade200;
    if (severity <= 8) return Colors.orange.shade200;
    return Colors.red.shade200;
  }
}

// 常用症状列表
class CommonSymptoms {
  static const List<String> physical = [
    '痛经', '头痛', '乳房胀痛', '疲劳', '恶心', '头晕',
    '腹泻', '便秘', '背痛', '情绪波动', '失眠', '食欲变化',
    '皮肤问题', '水肿', '关节疼痛'
  ];

  static const List<String> emotional = [
    '易怒', '焦虑', '抑郁', '情绪低落', '紧张', '注意力不集中',
    '记忆力减退', '心情烦躁', '幸福感降低', '敏感', '情绪化'
  ];
}

// 经期提醒设置模型
class PeriodReminder {
  final int id;
  final int userId;
  final bool enabled;
  final int daysInAdvance; // 提前几天提醒
  final String timeOfDay; // 提醒时间，格式：HH:mm
  final bool duringPeriod; // 是否在经期内提醒

  PeriodReminder({
    required this.id,
    required this.userId,
    this.enabled = true,
    this.daysInAdvance = 3,
    this.timeOfDay = '08:00',
    this.duringPeriod = true,
  });

  Map<String, dynamic> toMap() {
    return {
      'userId': userId,
      'enabled': enabled ? 1 : 0,
      'daysInAdvance': daysInAdvance,
      'timeOfDay': timeOfDay,
      'duringPeriod': duringPeriod ? 1 : 0,
    };
  }

  factory PeriodReminder.fromMap(Map<String, dynamic> map) {
    return PeriodReminder(
      id: map['id'],
      userId: map['userId'],
      enabled: map['enabled'] == 1,
      daysInAdvance: map['daysInAdvance'],
      timeOfDay: map['timeOfDay'],
      duringPeriod: map['duringPeriod'] == 1,
    );
  }
}

// 预测结果类
class PredictionResult {
  final DateTime nextPeriodDate;
  final DateTime ovulationDate;
  final List<DateTime> fertilityWindow;
  final int confidenceLevel; // 0-100的置信度
  final double avgCycleLength;
  final double avgPeriodLength;

  PredictionResult({
    required this.nextPeriodDate,
    required this.ovulationDate,
    required this.fertilityWindow,
    required this.confidenceLevel,
    required this.avgCycleLength,
    required this.avgPeriodLength,
  });

  // 获取特定日期的受孕概率
  double getPregnancyRateForDate(DateTime date) {
    // 计算日期与排卵日的差距
    final daysDiff = ovulationDate.difference(date).inDays.abs();
    
    if (daysDiff > 5) return 3.0; // 基础受孕率
    if (daysDiff == 0) return 33.0; // 排卵日最高
    if (daysDiff <= 1) return 30.0; // 排卵日前后一天
    if (daysDiff <= 2) return 20.0; // 排卵日前后两天
    return 8.0; // 其他易孕期
  }

  // 获取置信度文本
  String getConfidenceText() {
    if (confidenceLevel >= 90) return '非常高';
    if (confidenceLevel >= 75) return '较高';
    if (confidenceLevel >= 60) return '中等';
    if (confidenceLevel >= 40) return '较低';
    return '很低';
  }

  // 获取置信度颜色
  Color getConfidenceColor() {
    if (confidenceLevel >= 90) return Colors.green.shade700;
    if (confidenceLevel >= 75) return Colors.green.shade500;
    if (confidenceLevel >= 60) return Colors.yellow.shade600;
    if (confidenceLevel >= 40) return Colors.orange.shade500;
    return Colors.red.shade500;
  }
}

// 日历日模型
class CalendarDay {
  final DateTime date;
  final bool isToday;
  final bool isPeriod;
  final bool isPredictedPeriod;
  final bool isOvulation;
  final bool isFertile;
  final bool isSafe;
  final List<Symptom>? symptoms;
  final String? note;

  CalendarDay({
    required this.date,
    this.isToday = false,
    this.isPeriod = false,
    this.isPredictedPeriod = false,
    this.isOvulation = false,
    this.isFertile = false,
    this.isSafe = false,
    this.symptoms,
    this.note,
  });

  // 获取当天状态的显示文本
  String getStatusText() {
    if (isPeriod) return '经期';
    if (isPredictedPeriod) return '预测经期';
    if (isOvulation) return '排卵日';
    if (isFertile) return '易孕期';
    if (isSafe) return '安全期';
    return '正常';
  }

  // 获取当天状态的颜色
  Color getStatusColor() {
    if (isPeriod) return Colors.red.shade400;
    if (isPredictedPeriod) return Colors.red.shade200;
    if (isOvulation) return Colors.pink.shade400;
    if (isFertile) return Colors.purple.shade300;
    if (isSafe) return Colors.blue.shade200;
    return Colors.grey.shade200;
  }
}

// 周期统计数据
class CycleStatistics {
  final int totalPeriods;
  final double avgCycleLength;
  final double avgPeriodLength;
  final double regularityScore; // 0-100，表示周期规律性
  final int shortestCycle;
  final int longestCycle;
  final List<String> commonSymptoms;
  final int trackingDays;

  CycleStatistics({
    required this.totalPeriods,
    required this.avgCycleLength,
    required this.avgPeriodLength,
    required this.regularityScore,
    required this.shortestCycle,
    required this.longestCycle,
    required this.commonSymptoms,
    required this.trackingDays,
  });

  // 获取规律性描述
  String getRegularityDescription() {
    if (regularityScore >= 90) return '非常规律';
    if (regularityScore >= 75) return '比较规律';
    if (regularityScore >= 60) return '基本规律';
    if (regularityScore >= 40) return '不太规律';
    return '很不规律';
  }

  // 获取规律性颜色
  Color getRegularityColor() {
    if (regularityScore >= 90) return Colors.green.shade600;
    if (regularityScore >= 75) return Colors.green.shade400;
    if (regularityScore >= 60) return Colors.yellow.shade600;
    if (regularityScore >= 40) return Colors.orange.shade500;
    return Colors.red.shade500;
  }
}

// 用户配置模型
class UserPeriodPreferences {
  final int userId;
  final String theme; // 'light', 'dark', 'system'
  final bool notificationsEnabled;
  final bool symptomTrackingEnabled;
  final bool autoBackupEnabled;
  final String dateFormat; // 'yyyy-MM-dd', 'MM/dd/yyyy', etc.

  UserPeriodPreferences({
    required this.userId,
    this.theme = 'system',
    this.notificationsEnabled = true,
    this.symptomTrackingEnabled = true,
    this.autoBackupEnabled = true,
    this.dateFormat = 'yyyy-MM-dd',
  });

  Map<String, dynamic> toMap() {
    return {
      'userId': userId,
      'theme': theme,
      'notificationsEnabled': notificationsEnabled ? 1 : 0,
      'symptomTrackingEnabled': symptomTrackingEnabled ? 1 : 0,
      'autoBackupEnabled': autoBackupEnabled ? 1 : 0,
      'dateFormat': dateFormat,
    };
  }

  factory UserPeriodPreferences.fromMap(Map<String, dynamic> map) {
    return UserPeriodPreferences(
      userId: map['userId'],
      theme: map['theme'],
      notificationsEnabled: map['notificationsEnabled'] == 1,
      symptomTrackingEnabled: map['symptomTrackingEnabled'] == 1,
      autoBackupEnabled: map['autoBackupEnabled'] == 1,
      dateFormat: map['dateFormat'],
    );
  }
}